package com.michaelbulava.TFS;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleComponent;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vfs.VirtualFile;
import com.michaelbulava.TFS.configuration.ProjectPreferences;
import com.michaelbulava.TFS.log.FileLogger;
import com.michaelbulava.TFS.persistence.IdeaPersistenceStoreProvider;
import com.michaelbulava.TFS.tasks.BackgroundableTask;
import com.michaelbulava.TFS.tpignore.TPIgnoreCache;
import com.michaelbulava.TFS.tpignore.TPIgnoreDocument;
import com.michaelbulava.TFS.ui.dialogs.connect.ReconnectDialog;
import com.michaelbulava.TFS.ui.helpers.UIHelpers;
import com.michaelbulava.TFS.vcs.TFSVcs;
import com.michaelbulava.TFS.vcs.utils.TFSFileUtil;
import com.microsoft.tfs.core.clients.versioncontrol.Workstation;
import com.microsoft.tfs.core.clients.versioncontrol.exceptions.VersionControlException;
import com.microsoft.tfs.core.clients.versioncontrol.workspacecache.WorkspaceInfo;
import com.microsoft.tfs.util.xml.XMLException;
import org.jetbrains.annotations.NotNull;

import java.text.MessageFormat;


/**
 * Created by mbulava on 6/16/2015.
 *
 */
public class TFSVcsModuleComponent implements ModuleComponent{//, CheckModuleForWorkspace.WorkspaceCheckCompletedListener /*,JDOMExternalizable*/ {
    private static final Logger log = FileLogger.getInstance(TFSVcsModuleComponent.class);
    private static final String TFS_URL_ATTR = "TFS_url";
    private static final String ISOFFLINE_ATTR = "IsOffline";

    private final Module myModule;

    //private URI mTFS_ServerUri = null;
    //private boolean mIsOffline = false;

    public TFSVcsModuleComponent(Module module) {
        this.myModule = module;
    }

    public static TFSVcsModuleComponent getInstance(Module module){
        return module.getComponent(TFSVcsModuleComponent.class);
    }

    public void initComponent() {
        log.info("initComponent - Starting");
    }

    public void disposeComponent() {}

    @NotNull
    public String getComponentName() {
        return "TFSVcs.ModuleProperties";
    }

    public void projectOpened() {
        // called when project is opened
        log.info("projectOpened...");
    }

    public void projectClosed() {
        // called when project is being closed
        log.info("projectClosed...");
    }

    public void moduleAdded() {
        // Invoked when the module corresponding to this component instance has been completely
        // loaded and added to the project.
        //if (myModule.getProject().isInitialized()){
        //is the module controlled by TFS already?
        if (TFSVcs.isUnderTFS(myModule.getModuleFile(), myModule.getProject())){
            startModuleConnection();
        }
    }


    public void startModuleConnection(){
        WorkspaceInfo workspaceInfo = null;
        try{
            workspaceInfo = Workstation.getCurrent(IdeaPersistenceStoreProvider.INSTANCE)
                    .getLocalWorkspaceInfo(myModule.getModuleFile().getParent().getPath());

            if (workspaceInfo == null){
                WorkspaceInfo[] infos = Workstation.getCurrent(IdeaPersistenceStoreProvider.INSTANCE).getAllLocalWorkspaceInfo();
                for(WorkspaceInfo info : infos){
                    for(String mappedPath  : info.getMappedPaths()) {
                        FilePath MappedFolder = TFSFileUtil.getFilePath(mappedPath);
                        if (TFSFileUtil.getFilePath(myModule.getModuleFile()).isUnder(MappedFolder, false)){
                            workspaceInfo = info;
                            break;
                        }
                    }
                    if (workspaceInfo != null)
                        break;
                }
            }

            if (workspaceInfo == null)
                throw new VersionControlException();

        } catch(VersionControlException vce){
            if (vce.getCause() instanceof XMLException){
                //The VersionControl.config got corrupted some how, we need to fix it.
                IdeaPersistenceStoreProvider.INSTANCE.getCachePersistenceStore().deleteItem("VersionControl.config");
            }

            final BackgroundableTask eTask = new BackgroundableTask(myModule.getProject(), "Reconnect Module", false) {
                @Override
                protected boolean runInBackground() {
                    return true;
                }

                @Override
                public void run(@NotNull ProgressIndicator indicator) {
                    UIHelpers.runOnUIThread(false, new Runnable() {
                        @Override
                        public void run() {
                            ReconnectDialog dialog = new ReconnectDialog(myModule.getProject(),
                                    MessageFormat.format(Messages.getString("TFSVcsModuleComponent.CorruptVersionControlConfig_Message_Format"),
                                            new Object[]{ myModule.getName() }));

                            if (!dialog.showAndGet()){
                                log.error("User canceled reconnect dialog, TFS vcs will be disabled.");
                            } else {
                                //restart;
                                startModuleConnection();
                                TFSFileUtil.refreshAndInvalidate(myProject
                                        , new FilePath[]
                                        {
                                                TFSFileUtil.getFilePath(myModule.getModuleFile().getParent())
                                        }
                                        , true);
                            }
                        }
                    });
                }
            };

            ProgressManager.getInstance().run(eTask);

            return;
        } catch(Throwable tr){
            log.error("Failure occurred in module start-up", tr);
            return;
        }

        //Just incase the ignore document doesn't exist... Create it, it's holding a lot of good stuff..
        VirtualFile ignoreFile = TPIgnoreCache.getIgnoreFile(myModule);
        if (ignoreFile == null || !ignoreFile.exists())
            TPIgnoreDocument.createDefaultTPIgnoreDocument(myModule);

        TFSVcs.registerModuleForTFS(myModule, workspaceInfo, IsOffline());
    }



    public boolean IsOffline(){
        return ProjectPreferences.getProjectInstance(myModule.getProject()).getModuleIsOffline(myModule);
    }

    public void setOffline(boolean value){
        ProjectPreferences.getProjectInstance(myModule.getProject()).setModuleIsOffline(myModule, value);
    }

}
